<?php

namespace fadadaApi;

use fadadaApi\data\FddComplianceContractReport;
use fadadaApi\data\FddDocusignAcrosspage;
use fadadaApi\data\FddAccount;
use fadadaApi\data\FddAuthSign;
use fadadaApi\data\FddCertification;
use fadadaApi\data\FddContractManageMent;
use fadadaApi\data\FddQuerySignResult;
use fadadaApi\data\FddSignature;
use fadadaApi\data\FddSignatureContent;
use fadadaApi\data\FddSignContract;
use fadadaApi\data\FddTemplate;
use fadadaApi\data\FddGeneralParam;
use fadadaApi\data\FddSmsParam;

/**
 *
 * 接口访问类，包含所有法大大API列表的封装
 * 每个接口有默认超时时间
 */
date_default_timezone_set('PRC');//其中PRC为“中华人民共和国”
class FddApi
{
	protected string $app_id     = '';
	protected string $app_secret = '';
	protected string $fdd_server = '';
	protected string $Version    = '2.0';   // 接口版本号

	public function __construct(string $app_id = '', string $app_secret = '')
	{
		$this->app_id     = $app_id ?? config('fadada.AppId');
		$this->app_secret = $app_secret ?? config('fadada.AppSecret');
		$this->fdd_server = config('fadada.FddServer');
	}

	/**
	 * 4.1合规化接口 注册账号
	 *
	 *
	 * @return array|mixed
	 */
	public function registerAccount(FddAccount $param)
	{
		//注册接口
		$url = $this->fdd_server . '/account_register.api';
		try {
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			if (!$param->IsOpenIDSet())
				throw new FddException("缺少必填参数-open_id");
			if (!$param->IsAccountTypeSet())
				throw new FddException("缺少必填参数-account_type");
			$encArr = $param->GetValues();
			$encKey = array_keys($encArr);
			array_multisort($encKey);
			$enc = [
				'md5'  => [],
				'sha1' => $encKey
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			return self::https_request($url, $input);

		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}


	/**
	 * 4.2获取企业实名认证地址
	 *
	 * @param FddCertification $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function getCompanyVerifyUrl(FddCertification $param): array
	{
		//获取企业实名认证地址
		$url = $this->fdd_server . '/get_company_verify_url.api';
		try {
			// 参数处理
			if (!$param->IsCustomerIDSet()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsPageModifySet()) {
				throw new FddException("缺少必填参数-page_modify");
			}

			if ($param->IsAgentIDSet() && $param->IsAgentName() && $param->IsAgentIdFrontPath() && $param->IsAgentMobileSet() && $param->IsBankCardNoSet()) {
				$AgentInfo = [
					'agent_id'            => $param->GetAgentID(),
					'agent_id_front_path' => $param->GetAgentIdFrontPath(),
					'agent_mobile'        => $param->GetAgentMobile(),
					'agent_name'          => $param->GetAgentName(),
					'bank_card_no'        => $param->getBank_card_no()
				];
				$param->SetAgentInfo(json_encode($AgentInfo));
			}

			if ($param->IsBankIdSet()) {
				$bankInfo = [
					'bank_id'        => $param->GetBankId(),
					'bank_name'      => $param->GetBankName(),
					'subbranch_name' => $param->GetSubbranchName(),
				];
				$param->SetBankInfo(json_encode($bankInfo));
			}

			if ($param->IsCompanyNameSet()) {
				$companyInfo = [
					'company_name'      => $param->GetCompanyName(),
					'credit_image_path' => $param->GetCreditImagePath(),
					'credit_no'         => $param->GetCreditNo(),
				];
				$param->SetCompanyInfo(json_encode($companyInfo));
			}

			if ($param->IsLegalIdSet()) {
				$LegalInfo = [
					'legal_id'            => $param->GetLegalId(),
					'legal_id_front_path' => $param->GetlegaldIFrontPath(),
					'legal_name'          => $param->GetLegalName(),
					'legal_mobile'        => $param->GetlegalMobile(),
					'bank_card_no'        => $param->getBank_card_no()
				];
				$param->SetLegalnfo(json_encode($LegalInfo));
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);

			$encArr = $param->GetValues();
			$encKey = array_keys($encArr);
			// 删除字段名称，AgentInfo、bankInfo、companyInfo、LegalInfo的内部字段不直接参与摘要计算
			$encKey = array_diff($encKey, [
				"agent_id", "agent_id_front_path", "agent_mobile", "agent_name",
				"bank_card_no", 'bank_id', 'bank_name', 'subbranch_name', 'company_name', 'credit_image_path',
				'credit_no', 'legal_id', 'legal_id_front_path', 'legal_name', 'legal_mobile', 'm_verified_way'
			]);

			array_multisort($encKey);
			$enc = [
				'md5'  => [],
				'sha1' => $encKey
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);

		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 * 4.3获取个人实名认证地址
	 *
	 * @param FddCertification $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function getPersonVerifyUrl(FddCertification $param): array
	{
		//获取个人实名认证地址
		$url = $this->fdd_server . '/get_person_verify_url.api';
		try {
			// 参数处理
			if (!$param->IsCustomerIDSet()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsVerifiedWaySet()) {
				throw new FddException("缺少必填参数-verified_way");
			}
			if (!$param->IsPageModifySet()) {
				throw new FddException("缺少必填参数-page_modify");
			}

			//实例化3DES类
			$des    = new FddEncryption($this->app_id,$this->app_secret);
			$encArr = $param->GetValues();
			$encKey = array_keys($encArr);
			// 删除字段名称，file 类型参数
			$encKey = array_diff($encKey, ["ident_front_img", "ident_back_img"]);
			array_multisort($encKey);
			$enc = [
				'md5'  => [],
				'sha1' => $encKey
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);

		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 * 4.4实名证书申请接口
	 *
	 * @param FddCertification $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function ApplyCert(FddCertification $param): array
	{
		//获取实名证书申请接口
		$url = $this->fdd_server . '/apply_cert.api';
		try {
			// 参数处理
			if (!$param->IsCustomerIDSet()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsVerifiedSerialNo()) {
				throw new FddException("缺少必填参数-verified_serialno");
			}


			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id', 'verified_serialno']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);

		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}


	/**
	 * 4.5上传印章
	 *
	 * @param FddSignature $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function UploadSignature(FddSignature $param): array
	{
		//合同模板传输接口 地址
		$url = $this->fdd_server . '/add_signature.api';
		try {
			//参数处理
			if (!$param->IsCustomerId())
				throw new FddException("缺少必填参数-customer_id");
			if (!$param->IsSignatureImgBase64())
				throw new FddException("缺少必填参数-signature_img_base64");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id', 'signature_img_base64']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 * 4.6 自定义印章内容
	 *
	 * @param FddSignatureContent $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function UploadSignatureContent(FddSignatureContent $param): array
	{
		//合同模板传输接口 地址
		$url = $this->fdd_server . '/custom_signature.api';
		try {
			//参数处理
			if (!$param->IsCustomerId())
				throw new FddException("缺少必填参数-customer_id");
			if (!$param->IsContent())
				throw new FddException("缺少必填参数-content");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['content', 'customer_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}


	/**
	 *
	 * 4.7合同文档传输接口
	 * app_id、timestamp、msg_digest、v 、contract_id、doc_type 、doc_title必填参数
	 * file、doc_url  选填参数
	 *
	 * @param FddTemplate $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function Uploaddocs(FddTemplate $param): array
	{
		//合同文档传输接口 地址
		$url = $this->fdd_server . '/uploaddocs.api';
		try {
			//参数处理
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			if (!$param->IsDoc_titleSet())
				throw new FddException("缺少必填参数-doc_title");
			if (!$param->IsDoc_typeSet())
				throw new FddException("缺少必填参数-doc_type");
			if (!$param->IsFileSet() && !$param->IsDoc_urlSet())
				throw new FddException("缺少必填参数-file、doc_url 二选一");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_id']
			];
			// $param->SetMsg_digest($des->ContractDigest($param));
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			// file文件是为header 跳转
			// header('location:'.$url.$des->ArrayParamToStr($input));
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 4.8合同模板传输接口
	 * app_id、timestamp、msg_digest、v 、template_id 必填参数
	 * file、doc_url  选填参数
	 *
	 * @param FddTemplate $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function UploadTemplate(FddTemplate $param): array
	{
		//合同模板传输接口 地址
		$url = $this->fdd_server . '/uploadtemplate.api';
		try {
			//参数处理
			if (!$param->IsTemplate_idSet())
				throw new FddException("缺少必填参数-template_id");
			if (!$param->IsFileSet() && !$param->IsDoc_urlSet())
				throw new FddException("缺少必填参数-file、doc_url 二选一");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 4.9 模板填充生成合同接口
	 *
	 * 动态表单参数使用。参数实体用 FddTemplateDynamicTable。多个表格使用数组包装 FddTemplateDynamicTable。
	 * 然后使用 json_encode(array($你的数组变量), JSON_UNESCAPED_UNICODE) 赋值给 FddTemplate->SetDynamic_tables()
	 *
	 * app_id、timestamp、msg_digest、v 、template_id 必填参数
	 *
	 * @param FddTemplate $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function GenerateContract(FddTemplate $param): array
	{
		//合同生成接口 地址
		$url = $this->fdd_server . '/generate_contract.api';
		try {
			//参数处理
			if (!$param->IsTemplate_idSet())
				throw new FddException("缺少必填参数-template_id");
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			if (!$param->IsParameter_mapSet())
				throw new FddException("缺少必填参数-parameter_map");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
//            $data = [];
//            if($param->GetInsertWay() != null){
//                $data['insertWay'] = $param->GetInsertWay();
//            }
//            if($param->GetKeyword() != null){
//                $data['keyword'] = $param->GetKeyword();
//            }
//            if($param->GetPageBegin() != null){
//                $data['pageBegin'] = $param->GetPageBegin();
//            }
//            if($param->GetBorderFlag() != null){
//                $data['borderFlag'] = $param->GetBorderFlag();
//            }
//            if($param->GetCellHeight() != null){
//                $data['cellHeight'] = $param->GetCellHeight();
//            }
//            if($param->GetCellHorizontalAlignment() != null){
//                $data['cellHorizontalAlignment'] = $param->GetCellHorizontalAlignment();
//            }
//            if($param->GetCellVerticalAlignment() != null){
//                $data['cellVerticalAlignment'] = $param->GetCellVerticalAlignment();
//            }
//            if($param->GetTheFirstHeader() != null){
//                $data['theFirstHeader'] = $param->GetTheFirstHeader();
//            }
//            if($param->GetHeaders() != null){
//                $data['headers'] = $param->GetHeaders();
//            }
//            if($param->GetHeadersAlignment() != null){
//                $data['headersAlignment'] = $param->GetHeadersAlignment();
//            }
//            if($param->GetDatas() != null){
//               $data['datas']  = $param->GetDatas();
//            }
//            if($param->GetColWidthPercent() != null){
//                $data['colWidthPercent'] = $param->GetColWidthPercent();
//            }
//            if($param->GetTableHorizontalAlignment() != null){
//                $data['tableHorizontalAlignment'] = $param->GetTableHorizontalAlignment();
//            }
//            if($param->GetTableWidthPercentage() != null){
//                $data['tableWidthPercentage'] = $param->GetTableWidthPercentage();
//            }
//            if($param->GetTableHorizontalOffset() != null){
//                $data['tableHorizontalOffset'] = $param->GetTableHorizontalOffset();
//            }
//            $param->SetHeaders(json_encode($param->GetHeaders()));
//            $param->SetDatas(json_encode($param->GetDatas()));
//            $param->SetColWidthPercent(json_encode($param->GetColWidthPercent()));
//            $arr = array($data);
//            echo "count:".count($arr);
//            if (count($arr) >= 1){
//                $param->SetDynamic_tables(json_encode($arr));
//                echo "table:".$param->GetDynamic_tables();
//            }
//            if (!$param->IsHeadersSet())
//                    throw new FddException("缺少必填参数-headers");
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$param->SetMsg_digest($des->ContractDigest($param));
			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 4.10文档签署接口（自动签）
	 * app_id、timestamp、msg_digest、contract_id 、transaction_id、customer_id、必填参数
	 * notify_url 选填参数
	 *
	 * @param FddSignContract $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function ExtsignAuto(FddSignContract $param): array
	{
		// 文档签署接口（自动签） 地址
		$url = $this->fdd_server . '/extsign_auto.api';
		try {
			//参数处理
			if (!$param->IsTransaction_idSet())
				throw new FddException("缺少必填参数-transaction_id");
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			if (!$param->IsCustomer_idSet())
				throw new FddException("缺少必填参数-customer_id");
			if (!$param->IsDoc_titleSet())
				throw new FddException("缺少必填参数-doc_title");
			if (!$param->IsClient_roleSet())
				throw new FddException("缺少必填参数-client_role");
			if ($param->IsPosition_typeSet()) {
				if ($param->GetPosition_type() == 1) {
					if (!$param->IsSignature_positions_Set())
						throw new FddException("缺少必填参数- x 、y 、pagenum");
				}
				if ($param->GetPosition_type() == 0) {
					if (!$param->IsSign_keywordSet())
						throw new FddException("缺少必填参数- Sign_keyword");
				}
			}
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			$param->SetDoc_title(urlencode($param->GetDoc_title()));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$param->SetMsg_digest($des->ExtsignDigest($param));
			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 4.11文档签署接口（手动签）
	 * app_id、timestamp、msg_digest、contract_id 、transaction_id、customer_id、必填参数
	 * notify_url 选填参数
	 *
	 * @param FddSignContract $param
	 *
	 * @return array|string 成功时返回，其他抛异常
	 */
	public function Extsign(FddSignContract $param)
	{
		// 文档签署接口（手动签） 地址
		$url = $this->fdd_server . '/extsign.api';
		try {
			//参数处理
			if (!$param->IsTransaction_idSet())
				throw new FddException("缺少必填参数-transaction_id");
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			if (!$param->IsCustomer_idSet())
				throw new FddException("缺少必填参数-customer_id");
			if (!$param->IsDoc_titleSet())
				throw new FddException("缺少必填参数-doc_title");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			$param->SetDoc_title(urlencode($param->GetDoc_title()));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$param->SetMsg_digest($des->ExtsignDigest($param));
			$input = $param->GetValues();
//            header('location:'.$url.$des->ArrayParamToStr($input));
			// 2022-03-02 将手动签地址直接进行返回，不进行打开操作
			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);
			// $res = self::https_request($url,$input);
			// return $res;
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}


	/**
	 *
	 * 文档签署接口（含有效期和次数限制）
	 * app_id、timestamp、msg_digest、contract_id 、transaction_id 、customer_id、doc_title、return_url、validity、quantity必填参数
	 * notify_url 、sign_keyword 、keyword_strategy 选填参数
	 *
	 * @param FddSignContract $param
	 *
	 * @return array|string 成功时返回，其他抛异常
	 */
	public function ExtsignValidation(FddSignContract $param)
	{
		// 文档签署接口（含有效期和次数限制） 地址
		$url = $this->fdd_server . '/extsign_validation.api';
		try {
			//参数处理
			if (!$param->IsTransaction_idSet())
				throw new FddException("缺少必填参数-transaction_id");
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			if (!$param->IsCustomer_idSet())
				throw new FddException("缺少必填参数-customer_id");
			if (!$param->IsDoc_titleSet())
				throw new FddException("缺少必填参数-doc_title");
			if (!$param->IsReturn_urlSet())
				throw new FddException("缺少必填参数-return_url");
			if (!$param->IsValiditySet())
				throw new FddException("缺少必填参数-validity");
			if (!$param->IsQuantitySet())
				throw new FddException("缺少必填参数-quantity");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			$param->SetDoc_title(urlencode($param->GetDoc_title()));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$param->SetMsg_digest($des->ExtsignValiityDigest($param));
			$input = $param->GetValues();

			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);
			// $res = self::https_request($url,$input);
			// return $res;
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 客户签署结果查询接口
	 *
	 * @param FddQuerySignResult $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function QuerySignResult(FddQuerySignResult $param): array
	{
		//客户签署结果查询接口 地址
		$url = $this->fdd_server . '/query_sign_result.api';
		try {
			//参数处理
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			if (!$param->IsCustomer_idSet())
				throw new FddException("缺少必填参数-customer_id");
			if (!$param->IsTransaction_idSet())
				throw new FddException("缺少必填参数-transaction_id");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_id', 'customer_id', 'transaction_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 4.12文档查看接口
	 *
	 * @param FddContractManageMent $param
	 *
	 * @return array|string 成功时返回，其他抛异常
	 */
	public function ViewContract(FddContractManageMent $param)
	{
		//文档查看接口
		$url = $this->fdd_server . '/viewContract.api';
		try {
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();

			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);

			// $res = self::https_request($url,$input);
			// return $res;
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 文档临时查看/下载地址接口（含有效期和次数）
	 *
	 * @param FddContractManageMent $param
	 *
	 * @return array 成功时返回，其他抛异常 Geturl
	 */
	public function GetUrl(FddContractManageMent $param): array
	{
		//文档临时查看/下载地址接口（含有效期和次数）
		$url = $this->fdd_server . '/geturl.api';
		try {
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			if (!$param->IsValiditySet())
				throw new FddException("缺少必填参数-validity");
			if (!$param->IsQuantitySet())
				throw new FddException("缺少必填参数-quantity");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => ['validity', 'quantity'],
				'sha1' => ['contract_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			// header('location:'.$url.$des->ArrayParamToStr($input));
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 4.13文档下载接口
	 *
	 * @param FddContractManageMent $param
	 *
	 * @return array|string 成功时返回，其他抛异常
	 */
	public function DownLoadContract(FddContractManageMent $param)
	{
		//文档下载接口 地址
		$url = $this->fdd_server . '/downLoadContract.api';
		try {
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 查询合同hash值接口
	 * contract_id 必填参数
	 *
	 * @param FddContractManageMent $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function GetContractHash(FddContractManageMent $param): array
	{
		//查询合同hash值接口
		$url = $this->fdd_server . '/getContractHash.api';
		try {
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}


	/**
	 *
	 * 4.14合同归档接口
	 *
	 * @param FddContractManageMent $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function ContractFiling(FddContractManageMent $param): array
	{
		//合同归档接口
		$url = $this->fdd_server . '/contractFiling.api';
		try {
			if (!$param->IsContract_idSet())
				throw new FddException("缺少必填参数-contract_id");
			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			// header('location:'.$url.$des->ArrayParamToStr($input));
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 *  文档验签接口
	 * app_id、timestamp、msg_digest、doc_url、file必填参数
	 *
	 * @param FddSignContract $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function ContractVerify(FddSignContract $param): array
	{
		//  文档验签接口 地址
		$url = $this->fdd_server . '/contract_verify.api';
		try {
			//参数处理
			if (!$param->IsFileSet() && !$param->IsDoc_urlSet())
				throw new FddException("缺少必填参数-file、doc_url 二选一");

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			//设置加密串
			$enc = [
				'md5'  => [],
				'sha1' => ['doc_url']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 * 4.15两个接口为回调接口，法大大回调平台方
	 */

	/**
	 * 4.16查询个人实名认证信息
	 *
	 * @param FddCertification $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function FindPersonCertInfo(FddCertification $param): array
	{
		//查询个人实名认证信息
		$url = $this->fdd_server . '/find_personCertInfo.api';
		try {
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['verified_serialno']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);

		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 * 4.17查询企业实名认证信息
	 *
	 * @param FddCertification $param
	 *
	 * @return array 成功时返回，其他抛异常
	 */
	public function FindCompanyCertInfo(FddCertification $param): array
	{
		//查询企业实名认证信息
		$url = $this->fdd_server . '/find_companyCertInfo.api';
		try {
			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['verified_serialno']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);

		} catch (FddException $e) {

			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/**
	 *
	 * 4.18通过uuid下载文件
	 *
	 * @param \fadadaApi\data\FddCertification $param
	 *
	 * @return array|string 成功时返回，其他抛异常
	 */
	public function getFile(FddCertification $param)
	{
		// 通过uuid下载文件
		$url = $this->fdd_server . '/get_file.api';
		try {
			//参数处理
			if (!$param->IsUUID())
				throw new FddException("缺少必填参数-uuid");

			//实例化3DES类
			$des    = new FddEncryption($this->app_id,$this->app_secret);
			$encArr = $param->GetValues();
			$encKey = array_keys($encArr);
			// 参数升序排序
			array_multisort($encKey);
			$enc = [
				'md5'  => [],
				'sha1' => $encKey
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));
			$input = $param->GetValues();
			header('location:' . $url . $des->ArrayParamToStr($input));
//             $res = self::https_request($url,$input);
//             return $res;
			return $url . $des->ArrayParamToStr($input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}

	}

	/* =========================================== 2021-10-22 xjf 新增接口 === start =============================================*/


	/**
	 * 4.21 获取授权自动签页面接口
	 *
	 * @param FddAuthSign $param
	 *
	 * @return array|string
	 */
	public function BeforeAuthsign(FddAuthSign $param)
	{
		// 获取授权自动签页面接口
		$url = $this->fdd_server . '/before_authsign.api';

		try {
			// 参数处理
			if (!$param->IsTransaction_idSet()) {
				throw new FddException("缺少必填参数-transaction_id");
			}
			if (!$param->IsAuth_typeSet()) {
				throw new FddException("缺少必填参数-auth_type");
			}
			if (!$param->IsContract_idSet()) {
				throw new FddException("缺少必填参数-contract_id");
			}
			if (!$param->IsCustomerId()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsReturn_urlSet()) {
				throw new FddException("缺少必填参数-return_url");
			}
			if (!$param->IsNotify_urlSet()) {
				throw new FddException("缺少必填参数-notify_url");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => ['transaction_id'],
				'sha1' => ['customer_id']
			];
			$param->SetMsg_digest($des->AuthSignDigest($param, $enc));

			$input = $param->GetValues();
//            return self::https_request($url,$input);
			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 4.22 查询授权自动签状态接口
	 *
	 * @param FddAuthSign $param
	 *
	 * @return array|mixed
	 */
	public function GetAuthStatus(FddAuthSign $param)
	{
		// 查询授权自动签状态接口
		$url = $this->fdd_server . '/get_auth_status.api';

		try {
			// 参数处理
			if (!$param->IsCustomerId()) {
				throw new FddException("缺少必填参数-customer_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id']
			];
			$param->SetMsg_digest($des->AuthSignDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 4.23 取消授权签协议接口
	 *
	 * @param FddAuthSign $param
	 *
	 * @return array|mixed
	 */
	public function CancelExtsignAutoPage(FddAuthSign $param)
	{
		// 取消授权签协议接口
		$url = $this->fdd_server . '/cancel_extsign_auto_page.api';

		try {
			// 参数处理
			if (!$param->IsCustomerId()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsReturn_urlSet()) {
				throw new FddException("缺少必填参数-return_url");
			}
			if (!$param->IsNotify_urlSet()) {
				throw new FddException("缺少必填参数-notify_url");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id', 'notify_url', 'return_url']
			];
			$param->SetMsg_digest($des->AuthSignDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 客户签署状态查询接口
	 *
	 * @param FddGeneralParam $param
	 *
	 * @return array|mixed
	 */
	public function QuerySignstatus(FddGeneralParam $param)
	{
		// 客户签署状态查询接口
		$url = $this->fdd_server . '/query_signstatus.api';

		try {
			// 参数处理
			if (!$param->IsCustomerId()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsContract_idSet()) {
				throw new FddException("缺少必填参数-contract_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_id', 'customer_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 文档批量下载接口
	 *
	 * @param FddContractManageMent $param
	 *
	 * @return array|mixed
	 */
	public function BatchDownloadContract(FddContractManageMent $param)
	{
		// 文档批量下载接口
		$url = $this->fdd_server . '/batch_download_contract.api';

		try {
			// 参数处理
			if (!$param->IsContract_idsSet()) {
				throw new FddException("缺少必填参数-contract_ids");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_ids']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 生成短链接口
	 *
	 * @param FddSignContract $param
	 *
	 * @return array|mixed
	 */
	public function ShortUrl(FddSignContract $param)
	{
		// 生成短链接口
		$url = $this->fdd_server . '/short_url.api';

		try {
			// 参数处理
			if (!$param->IsSource_urlSet()) {
				throw new FddException("缺少必填参数-source_url");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['expire_time', 'source_url']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 自定义短信发送短链接口
	 *
	 * @param FddSmsParam $param
	 *
	 * @return array|mixed
	 */
	public function PushShortUrlSms(FddSmsParam $param)
	{
		// 自定义短信发送短链接口
		$url = $this->fdd_server . '/push_short_url_sms.api';

		try {
			// 参数处理
			if (!$param->IsSource_urlSet()) {
				throw new FddException("缺少必填参数-source_url");
			}
			if (!$param->IsExpire_timeSet()) {
				throw new FddException("缺少必填参数-expire_time");
			}
			if (!$param->IsMobile()) {
				throw new FddException("缺少必填参数-mobile");
			}
			if (!$param->IsMessage_typeSet()) {
				throw new FddException("缺少必填参数-message_type");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['expire_time', 'message_content', 'message_type', 'mobile', 'sms_template_type', 'source_url']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 自定义短信发送接口
	 *
	 * @param FddSmsParam $param
	 *
	 * @return array|mixed
	 */
	public function SmsText(FddSmsParam $param)
	{
		// 自定义短信发送接口
		$url = $this->fdd_server . '/sms_text.api';

		try {
			// 参数处理
			if (!$param->IsMobile()) {
				throw new FddException("缺少必填参数-mobile");
			}
			if (!$param->IsMessage_typeSet()) {
				throw new FddException("缺少必填参数-message_type");
			}

			// 手机号加密：encrypt_type：不传默认为0。
			//                     0-3DES，密钥为appsecret，
			//                     1-SM4（ECB模式），密钥为appsecret转为16进制后取后32位。（此方式不做）
			//                     2-不加密
			if ($param->IsEncrypt_typeSet()) {
				if ("0" == $param->GetEncrypt_type()) {
					$encrypt = new FddEncryption($this->app_id,$this->app_secret);
					$param->SetMobile($encrypt->encrypt($param->getMobile()));
				}
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => ['mobile', 'message_type', 'message_content', 'code', 'encrypt_type'],
				'sha1' => []
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 电子文件签署线上出证专业版接口
	 *
	 * @param FddComplianceContractReport $param
	 *
	 * @return array|mixed
	 */
	public function ComplianceContractReport(FddComplianceContractReport $param)
	{
		// 电子文件签署线上出证专业版接口
		$url = $this->fdd_server . '/api/compliance-contract-report';

		try {
			// 参数处理
			if (!$param->IsContractNumSet()) {
				throw new FddException("缺少必填参数-contractNum");
			}

			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['contractNum', 'account']
			];
			$param->SetMsgDigest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 查看合同模板
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|string
	 */
	public function ViewTemplate(FddTemplate $param)
	{
		// 查看合同模板
		$url = $this->fdd_server . '/view_template.api';

		try {
			// 参数处理
			if (!$param->IsTemplate_idSet()) {
				throw new FddException("缺少必填参数-template_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 合同模板下载
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|mixed
	 */
	public function DownloadTemplate(FddTemplate $param)
	{
		// 合同模板下载
		$url = $this->fdd_server . '/api/download_template.api';

		try {
			// 参数处理
			if (!$param->IsTemplate_idSet()) {
				throw new FddException("缺少必填参数-template_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 合同模板删除
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|mixed
	 */
	public function TemplateDelete(FddTemplate $param)
	{
		// 合同模板删除
		$url = $this->fdd_server . '/api/template_delete.api';

		try {
			// 参数处理
			if (!$param->IsTemplate_idSet()) {
				throw new FddException("缺少必填参数-template_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 合同模板图片下载
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|mixed
	 */
	public function DownloadTemplateImgs(FddTemplate $param)
	{
		// 合同模板图片下载
		$url = $this->fdd_server . '/api/download_template_imgs.api';

		try {
			// 参数处理
			if (!$param->IsTemplate_idSet()) {
				throw new FddException("缺少必填参数-template_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 获取 pdf 模版表单域 key 值接口
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|mixed
	 */
	public function GetPdftemplateKeys(FddTemplate $param)
	{
		// 获取 pdf 模版表单域 key 值接口
		$url = $this->fdd_server . '/api/get_pdftemplate_keys.api';

		try {
			// 参数处理
			if (!$param->IsTemplate_idSet()) {
				throw new FddException("缺少必填参数-template_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 添加表单域到模板
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|mixed
	 */
	public function AddKeys(FddTemplate $param)
	{
		// 添加表单域到模板
		$url = $this->fdd_server . '/api/add_keys.api';

		try {
			// 参数处理
			if (!$param->IsContract_template_idSet()) {
				throw new FddException("缺少必填参数-contract_template_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 上传合同模板接口
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|mixed
	 */
	public function UploadTemplateDocs(FddTemplate $param)
	{
		// 上传合同模板接口
		$url = $this->fdd_server . '/api/upload_template_docs.api';

		try {
			// 参数处理
			if (!$param->IsContract_template_idSet()) {
				throw new FddException("缺少必填参数-contract_template_id");
			}
			if (!$param->IsFileSet()) {
				throw new FddException("缺少必填参数-file");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 根据模板id跳转编辑页面
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|string
	 */
	public function GetDocStream(FddTemplate $param)
	{
		// 根据模板id跳转编辑页面
		$url = $this->fdd_server . '/api/get_doc_stream.api';

		try {
			// 参数处理
			if (!$param->IsContract_template_idSet()) {
				throw new FddException("缺少必填参数-contract_template_id");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 跳转合同填充页面接口
	 *
	 * @param FddTemplate $param
	 *
	 * @return array|string
	 */
	public function FillPage(FddTemplate $param)
	{
		// 跳转合同填充页面接口
		$url = $this->fdd_server . '/api/fill_page.api';

		try {
			// 参数处理
			if (!$param->IsContract_template_idSet()) {
				throw new FddException("缺少必填参数-contract_template_id");
			}
			if (!$param->IsContract_idSet()) {
				throw new FddException("缺少必填参数-contract_id");
			}
			if (!$param->IsDoc_titleSet()) {
				throw new FddException("缺少必填参数-doc_title");
			}

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['contract_id', 'contract_template_id']
			];
			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 快捷签署接口（个人）
	 *
	 * @param FddSignContract $param
	 *
	 * @return array|mixed
	 */
	public function PersonVerifySign(FddSignContract $param)
	{
		// 快捷签署接口（个人）
		$url = $this->fdd_server . '/api/person_verify_sign.api';

		try {
			// 参数处理
			if (!$param->IsTransaction_idSet()) {
				throw new FddException("缺少必填参数-transaction_id");
			}
			if (!$param->IsContract_idSet()) {
				throw new FddException("缺少必填参数-contract_id");
			}
			if (!$param->IsCustomer_idSet()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsNotify_urlSet()) {
				throw new FddException("缺少必填参数-notify_url");
			}
			if (!$param->IsPageModifySet()) {
				throw new FddException("缺少必填参数-page_modify");
			}
			if (!$param->IsVerified_notify_urlSet()) {
				throw new FddException("缺少必填参数-verified_notify_url");
			}
			if (!$param->IsVerifiedWaySet()) {
				throw new FddException("缺少必填参数-verified_way");
			}

			//实例化3DES类
			$des    = new FddEncryption($this->app_id,$this->app_secret);
			$encArr = $param->GetValues();
			$encKey = array_keys($encArr);
			// 参数升序排序
			array_multisort($encKey);
			$enc = [
				'md5'  => [],
				'sha1' => $encKey
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 批量快捷签署接口（个人）
	 *
	 * @param FddSignContract $param
	 *
	 * @return array|mixed
	 */
	public function BatchQuickSign(FddSignContract $param)
	{
		// 批量快捷签署接口（个人）
		$url = $this->fdd_server . '/api/batch_quick_sign.api';

		try {
			// 参数处理
			if (!$param->IsCustomer_idSet()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsBatch_idSet()) {
				throw new FddException("缺少必填参数-batch_id");
			}
			if (!$param->IsSign_dataSet()) {
				throw new FddException("缺少必填参数-sign_data");
			}
			if (!$param->IsBatch_titleSet()) {
				throw new FddException("缺少必填参数-batch_title");
			}
			if (!$param->IsReturn_urlSet()) {
				throw new FddException("缺少必填参数-return_url");
			}
			if (!$param->IsNotify_urlSet()) {
				throw new FddException("缺少必填参数-notify_url");
			}
			if (!$param->IsPageModifySet()) {
				throw new FddException("缺少必填参数-page_modify");
			}
			if (!$param->IsVerified_notify_urlSet()) {
				throw new FddException("缺少必填参数-verified_notify_url");
			}
			if (!$param->IsVerifiedWaySet()) {
				throw new FddException("缺少必填参数-verified_way");
			}

			// sign_data 使用 URLEncoder，编码UTF-8
			$param->SetSign_data(urlencode($param->GetSign_data()));

			//实例化3DES类
			$des    = new FddEncryption($this->app_id,$this->app_secret);
			$encArr = $param->GetValues();
			$encKey = array_keys($encArr);
			// 参数升序排序
			array_multisort($encKey);
			$enc = [
				'md5'  => [],
				'sha1' => $encKey
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 骑缝章自动签
	 *
	 * @param FddDocusignAcrosspage $param
	 *
	 * @return array|mixed
	 */
	public function DocusignAcrosspage(FddDocusignAcrosspage $param)
	{
		// 骑缝章自动签
		$url = $this->fdd_server . '/api/docusign_acrosspage.api';

		try {
			// 参数处理
			if (!$param->IsTransaction_idSet()) {
				throw new FddException("缺少必填参数-transaction_id");
			}
			if (!$param->IsContract_idSet()) {
				throw new FddException("缺少必填参数-contract_id");
			}
			if (!$param->IsCustomer_idSet()) {
				throw new FddException("缺少必填参数-customer_id");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['transaction_id', 'contract_id', 'customer_id']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 文档批量签署接口(半自动模式)
	 *
	 * @param FddSignContract $param
	 *
	 * @return array|string
	 */
	public function GotoBatchSemiautoSignPage(FddSignContract $param)
	{
		// 文档批量签署接口(半自动模式)
		$url = $this->fdd_server . '/api/gotoBatchSemiautoSignPage.api';

		try {
			// 参数处理
			if (!$param->IsBatch_idSet()) {
				throw new FddException("缺少必填参数-batch_id");
			}
			if (!$param->IsBatch_titleSet()) {
				throw new FddException("缺少必填参数-batch_title");
			}
			if (!$param->IsSign_dataSet()) {
				throw new FddException("缺少必填参数-sign_data");
			}
			if (!$param->IsCustomer_idSet()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsReturn_urlSet()) {
				throw new FddException("缺少必填参数-return_url");
			}

			// sign_data 使用 URLEncoder，编码UTF-8
			$param->SetSign_data(urlencode($param->GetSign_data()));

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => ['batch_id'],
				'sha1' => ['customer_id', 'outh_customer_id']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->AuthSignDigest($param, $enc));

			$input = $param->GetValues();
			// 注意：如果是用作 web ，则使用 htmlspecialchars 方法，防止转义
//            return htmlspecialchars($url.$des->ArrayParamToStr($input));
			return $url . $des->ArrayParamToStr($input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 文档批量签署接口（全自动模式）
	 *
	 * @param FddSignContract $param
	 *
	 * @return array|mixed
	 */
	public function ExtBatchSignAuto(FddSignContract $param)
	{
		// 文档批量签署接口（全自动模式）
		$url = $this->fdd_server . '/api/extBatchSignAuto.api';

		try {
			// 参数处理
			if (!$param->IsBatch_idSet()) {
				throw new FddException("缺少必填参数-batch_id");
			}
			if (!$param->IsBatch_titleSet()) {
				throw new FddException("缺少必填参数-batch_title");
			}
			if (!$param->IsSign_dataSet()) {
				throw new FddException("缺少必填参数-sign_data");
			}
			if (!$param->IsNotify_urlSet()) {
				throw new FddException("缺少必填参数-notify_url");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => ['batch_id'],
				'sha1' => ['sign_data']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->AuthSignDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 企业授权接口
	 *
	 * @param FddSignature $param
	 *
	 * @return array|mixed
	 */
	public function Authorization(FddSignature $param)
	{
		// 企业授权接口
		$url = $this->fdd_server . '/api/authorization.api';

		try {
			// 参数处理
			if (!$param->IsCompany_id()) {
				throw new FddException("缺少必填参数-company_id");
			}
			if (!$param->IsPerson_id()) {
				throw new FddException("缺少必填参数-person_id");
			}
			if (!$param->IsOperate_type()) {
				throw new FddException("缺少必填参数-operate_type");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['company_id', 'person_id', 'operate_type']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 企业印章单个授权接口
	 *
	 * @param FddSignature $param
	 *
	 * @return array|mixed
	 */
	public function AuthorizeSignature(FddSignature $param)
	{
		// 企业印章单个授权接口
		$url = $this->fdd_server . '/api/authorize_signature.api';

		try {
			// 参数处理
			if (!$param->IsCompany_id()) {
				throw new FddException("缺少必填参数-company_id");
			}
			if (!$param->IsPerson_id()) {
				throw new FddException("缺少必填参数-person_id");
			}
			if (!$param->IsOperate_type()) {
				throw new FddException("缺少必填参数-operate_type");
			}
			if (!$param->IsSignature_id()) {
				throw new FddException("缺少必填参数-signature_id");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['company_id', 'operate_type', 'person_id', 'signature_id']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 查询印章授权关系
	 *
	 * @param FddSignature $param
	 *
	 * @return array|mixed
	 */
	public function FindSignatureAuthList(FddSignature $param)
	{
		// 查询印章授权关系
		$url = $this->fdd_server . '/api/find_signature_auth_list.api';

		try {
			// 参数处理
			if (!$param->IsTypeSet()) {
				throw new FddException("缺少必填参数-type");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id', 'signature_id', 'type']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 查询签章接口
	 *
	 * @param FddSignature $param
	 *
	 * @return array|mixed
	 */
	public function QuerySignature(FddSignature $param)
	{
		// 查询签章接口
		$url = $this->fdd_server . '/api/query_signature.api';

		try {
			// 参数处理
			if (!$param->IsCustomerId()) {
				throw new FddException("缺少必填参数-customer_id");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id', 'signature_id']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 替换签章接口
	 *
	 * @param FddSignature $param
	 *
	 * @return array|mixed
	 */
	public function ReplaceSignature(FddSignature $param)
	{
		// 替换签章接口
		$url = $this->fdd_server . '/api/replace_signature.api';

		try {
			// 参数处理
			if (!$param->IsCustomerId()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsSignature_id()) {
				throw new FddException("缺少必填参数-signature_id");
			}
			if (!$param->IsSignatureImgBase64()) {
				throw new FddException("缺少必填参数-signature_img_base64");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id', 'signature_id', 'signature_img_base64']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 删除签章接口
	 *
	 * @param FddSignature $param
	 *
	 * @return array|mixed
	 */
	public function RemoveSignature(FddSignature $param)
	{
		// 删除签章接口
		$url = $this->fdd_server . '/api/remove_signature.api';

		try {
			// 参数处理
			if (!$param->IsCustomerId()) {
				throw new FddException("缺少必填参数-customer_id");
			}
			if (!$param->IsSignature_id()) {
				throw new FddException("缺少必填参数-signature_id");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id', 'signature_id']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}

	/**
	 * 设置默认章接口
	 *
	 * @param FddSignature $param
	 *
	 * @return array|mixed
	 */
	public function DefaultSignature(FddSignature $param)
	{
		// 设置默认章接口
		$url = $this->fdd_server . '/api/default_signature.api';

		try {
			// 参数处理
			if (!$param->IsCustomerId()) {
				throw new FddException("缺少必填参数-customer_id");
			}

			//实例化3DES类
			$des = new FddEncryption($this->app_id,$this->app_secret);
			$enc = [
				'md5'  => [],
				'sha1' => ['customer_id', 'signature_id']
			];

			$param->SetApp_id($this->app_id);
			$param->SetTimestamp(date('YmdHis'));
			if (!$param->IsVSet()) {
				$param->SetV($this->Version);
			}

			$param->SetMsg_digest($des->GeneralDigest($param, $enc));

			$input = $param->GetValues();
			return self::https_request($url, $input);
		} catch (FddException $e) {
			return ['result' => 'error', 'code' => 2001, 'msg' => $e->errorMessage()];
		}
	}


	/* =========================================== 2021-10-22 xjf 新增接口 === end =============================================*/


	/**
	 * 通用http函数
	 *
	 * @param              $url
	 * @param string|array $data
	 * @param string       $type
	 * @param string       $res
	 *
	 * @return mixed
	 */
	public function https_request($url, $data = "", string $type = "post", string $res = "json")
	{
		//1.初始化curl
		$curl = curl_init();
		// 设置 utf-8 编码
		$this_header = [
			"charset=UTF-8"
		];
		//2.设置curl的参数
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($curl, CURLOPT_HTTPHEADER, $this_header);
		if ($type == "post") {
			curl_setopt($curl, CURLOPT_POST, 1);
			curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
		}
		//3.采集
		$output = curl_exec($curl);
		//4.关闭
		curl_close($curl);
		if ($res == "json") {
			return json_decode($output, true);
		}
		return $output;
	}

	/**
	 * 文件输出http函数
	 *
	 * @param        $url
	 * @param string $data
	 * @param string $type
	 *
	 * @return void
	 */
	public function https_request_file($url, string $data = "", string $type = "post")
	{
		//1.初始化curl
		$curl = curl_init();
		//2.设置curl的参数
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		if ($type == "post") {
			curl_setopt($curl, CURLOPT_POST, 1);
			curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
		}
		//3.采集
		$output = curl_exec($curl);
		header("Content-type: application/octet-stream");

		header("Content-Disposition: attachment; filename=原文出证" . time() . ".pdf");

		echo $output;

		//4.关闭
		curl_close($curl);
	}

	/**
	 * 图片转base64文件
	 *
	 * @param $image_file
	 *
	 * @return string
	 */
	public function base64EncodeImage($image_file): string
	{
		$image_info   = getimagesize($image_file);
		$image_data   = fread(fopen($image_file, "r"), filesize($image_file));
		return "data:" . $image_info["mime"] . ";base64," . chunk_split(base64_encode($image_data));
	}

}